##
# In-game interface for the WTF RTS
##

from WtfEngine import *;
import WtfGui;
from Control import *;
import Multipliers;
import Traits;
import Technology;
import Trade;
import Commodities;


font = WtfGui.Font("v_gui_font");


#### Top menus

class MainMenu(WtfGui.Menu):
	def __init__(self, gmenu, wm):
		WtfGui.Menu.__init__(self, "Game");
		self.size = iVector2D(150, 0);
		
		self.AddChild(WtfGui.Button(Function(lambda: Controller.GetInst().EndTurn()),
			"End Turn", font));
		self.AddChild(WtfGui.Button(Function(lambda: gmenu.WmToggle()),
			"Game Menu", font));
		
			
class EmpireMenu(WtfGui.Menu):
	def __init__(self, gmenu, wm):
		WtfGui.Menu.__init__(self, "Empire");
		self.size = iVector2D(150, 0);
		
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(GovtReserves(Controller.GetInst().GetPlayerSociety()), 1)),
			"Reserves", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(GovtEconomy(Controller.GetInst().GetPlayerSociety()), 1)), 
			"Economy", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(GovtReserves(Controller.GetInst().GetPlayerSociety()), 1)),
			"Military", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(GovtEconomy(Controller.GetInst().GetPlayerSociety()), 1)), 
			"Science", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(GovtEconomy(Controller.GetInst().GetPlayerSociety()), 1)), 
			"Welfare", font));

class DataMenu(WtfGui.Menu):
	def __init__(self, gmenu, wm):
		WtfGui.Menu.__init__(self, "Data");
		self.size = iVector2D(150, 0);
		
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(News(), 1)), "News", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(MarketData(Controller.GetInst().GetPlayerSociety().GetCentralMarket()), 1)), "Industries", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(MarketData(Controller.GetInst().GetPlayerSociety().GetCentralMarket()), 1)), "Markets", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(MarketData(Controller.GetInst().GetPlayerSociety().GetCentralMarket()), 1)), "Companies", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(Help(wm), 1)), "Help", font));

class HelpMenu(WtfGui.Menu):
	def __init__(self, gmenu, wm):
		WtfGui.Menu.__init__(self, "Help");
		self.size = iVector2D(150, 0);
		
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(News(), 1)), "Rankings", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(MarketData(Controller.GetInst().GetPlayerSociety().GetCentralMarket()), 1)), "Demographics", font));
		self.AddChild(WtfGui.Button(Function(
			lambda: wm.AddWindow(Help(wm), 1)), "Help", font));
			
class TopBar(WtfGui.LayoutContainer):
	def __init__(self, ctrOpts, gmenu, wm):
		WtfGui.LayoutContainer.__init__(self, ctrOpts, 0);
		
		self.lblCash = WtfGui.Label("$$ 10000", font);
		self.AddChild(self.lblCash);
		
		self.AddChild(MainMenu(gmenu, wm));
		self.AddChild(EmpireMenu(gmenu, wm));
		self.AddChild(DataMenu(gmenu, wm));
		self.AddChild(HelpMenu(gmenu, wm));
		
		self.lblCash.ExpandToText();
		
class Radar(WtfGui.WidgetContainer):
	def __init__(self):
		WtfGui.WidgetContainer.__init__(self, "");
		
		lbl = WtfGui.Label("RADAR HERE", WtfGui.Font("v_gui_font"));
		self.AddChild(WtfGui.LayoutPositioner(lbl, WtfGui.CentrePositioner(), WtfGui.TopPositioner()));
		
		lbl.ExpandToText();
		self.Resize(200, 200);

class Button(WtfGui.ButtonEx):
	def __init__(self, onClick, onRtClick):
		ctrOpts = WtfGui.LayoutContainerCreationOptions();
		
		WtfGui.ButtonEx.__init__(self, ctrOpts);
		
		img = WtfGui.Image(TextureRef("media/images/RtsButtons/stopOrder.png"));
		img.Resize(48, 48);
		self.AddChild(img);
		
		self.onPress = Function(onClick);
		if(onRtClick != 0):
			self.onRightClick = Function(onRtClick);
		
		
#
# The actual interface. This also encapsulates the game state (by the window manager)
#
class Interface(WtfGui.ScreenOverlay):
	def __init__(self):
		
		WtfGui.ScreenOverlay.__init__(self);
		
		
		ctrOpts = WtfGui.LayoutContainerCreationOptions();
		
		# Game menu
		menu = GameMenu();
		menu.BindToEvent(KeyDownEvent(InputKey(27,0)));
		
		# Create bars
		self.topBar = TopBar(ctrOpts, menu, self);
		self.leftBar = WtfGui.LayoutContainer(ctrOpts, 1);
		self.rightBar = WtfGui.LayoutContainer(ctrOpts, 1);
		self.bottomBar = WtfGui.LayoutContainer(ctrOpts, 0);
		
		# Radar
		self.radar = Radar();
		
		# Add elements
		self.AddChild(WtfGui.LayoutPositioner(self.topBar, WtfGui.CentrePositioner(), WtfGui.TopPositioner()));
		self.AddChild(WtfGui.LayoutPositioner(self.leftBar, WtfGui.LeftPositioner(), WtfGui.CentrePositioner()));
		self.AddChild(WtfGui.LayoutPositioner(self.rightBar, WtfGui.RightPositioner(), WtfGui.CentrePositioner()));
		self.AddChild(WtfGui.LayoutPositioner(self.bottomBar, WtfGui.CentrePositioner(), WtfGui.BottomPositioner()));
		
		self.AddChild(WtfGui.LayoutPositioner(self.radar, WtfGui.LeftPositioner(), WtfGui.BottomPositioner()));

		# Listen to selection changes
		Controller.GetInst().Listen(self.OnSelectionChange);
	
	def Init(self):
		#Controller.GetInst().onPlayerStartTurn.append(
		#	lambda plyr: plyr.AddWindow(News()));
		WtfGui.ScreenOverlay.Init(self);
		
	def OnSelectionChange(self):
		self.leftBar.Clear();
		self.bottomBar.Clear();
		map(self.AddOrder, Controller.GetInst().orders);
		
	def AddOrder(self, order):
		if(order.button == None):
			order.button = Button(Function(lambda: Controller.GetInst().InvokeOrder(order)), 0);
		if(isinstance(order, Orders.BuildOrder)):
			self.bottomBar.AddChild(order.button);
		else:
			self.leftBar.AddChild(order.button);

			
class MarketData(WtfGui.Window):
	class CommodityGraph(WtfGui.Window):
		class DataProvider(WtfGui.GraphDataProvider):
			def __init__(self, mkt, name):
				WtfGui.GraphDataProvider.__init__(self);
				
				self.market = mkt;
				self.name = name;
				
			def GetNumValues(self):
				return len(self.market.marketHistory);
			def GetLabel(self, x):
				return str(x);
			def GetValue(self, x):
				if not x in self.market.marketHistory:
					return 0.0;
				data = self.market.marketHistory[x];
				if self.name in data:
					return data[self.name].avgPrice;
				else:
					return 0.0;
			
		def __init__(self, mkt, name):
			WtfGui.Window.__init__(self, name);
			
			self.axes = WtfGui.LineGraph("Turn", "Value");
			
			WtfGui.AutoLayout(self.axes.layout,
				WtfGui.AutoLayout.Default(), WtfGui.AutoLayout.Default(), 
				WtfGui.LRInnerSizeOf(self.layout),
				WtfGui.LRInnerSizeOf(self.layout));
				
			self.AddChild(self.axes);
			
			dp = MarketData.CommodityGraph.DataProvider(mkt, name);
			self.axes.AddGraph(WtfGui.GraphEntry(dp));
		
	def __init__(self, mkt):
		WtfGui.Window.__init__(self, "Market Data");
		
		self.market = mkt;
		self.font = WtfGui.Font("v_gui_font");
		
		self.table = WtfGui.Table(WtfGui.ScrollLayoutCreationOptions(), 1);
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 6.0, WtfGui.Label("Commodity", self.font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 6.0, WtfGui.Label("Avg. Price", self.font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 6.0, WtfGui.Label("Best Price", self.font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 6.0, WtfGui.Label("Volume", self.font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 6.0, WtfGui.Label("Mkt. Cap", self.font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 6.0, WtfGui.Label("Trade", self.font)));
		
		self.btnTraders = WtfGui.Button(Function(lambda:
			Controller.GetInst().currentPlayer.AddWindow(Traders(mkt))),
			"Traders", self.font);
		self.btnTraders.ExpandToText();
		
		# Update
		self.trade = mkt.GetTradeAmounts();
		map(lambda (k,v): self.AddObject(k, v), mkt.GetMarketData().iteritems());
		
		# Layout
		WtfGui.AutoLayout(self.table.layout,
			WtfGui.AutoLayout.Default(), WtfGui.AutoLayout.Default(), 
			WtfGui.LRInnerSizeOf(self.layout),
			WtfGui.LRInnerSizeOf(self.layout).Then(WtfGui.LRDisplacement(-30)));
		WtfGui.AutoLayout(self.btnTraders.layout,
			WtfGui.AutoLayout.Default(), WtfGui.AutoLayout.PositionAfter(self.table.layout),
			WtfGui.AutoLayout.Default(), WtfGui.AutoLayout.Default());
			
		self.AddChild(self.table);
		self.AddChild(self.btnTraders);
		
		self.innerSize.x = 600;
		
	def AddObject(self, n, c):
		rec = self.table.AddRecord();
		rec.AddChild(WtfGui.Button(Function(
			lambda: Controller.GetInst().currentPlayer.AddWindow(MarketData.CommodityGraph(self.market, n))), n, self.font));
		rec.AddChild(WtfGui.Label(str(c.avgPrice), self.font));
		rec.AddChild(WtfGui.Label(str(c.bestPrices.popitem()[0]), self.font));
		rec.AddChild(WtfGui.Label(str(c.vol), self.font));
		rec.AddChild(WtfGui.Label(str(c.mktCap), self.font));
		rec.AddChild(WtfGui.Label(self.GetTrade(n), self.font));

	def GetTrade(self, n):
		if n in self.trade:
			return str(self.trade[n]);
		else:
			return "0";

class Traders(WtfGui.Window):
	def __init__(self, mkt):
		WtfGui.Window.__init__(self, "Traders at Some Market");
		
		self.table = WtfGui.Table(WtfGui.ScrollLayoutCreationOptions(), 1);
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 3.0, WtfGui.Label("Name", font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 3.0, WtfGui.Label("Supply", font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 3.0, WtfGui.Label("Demand", font)));
		
		
		# Update
		map(lambda t: self.AddObject(t), mkt.traders);
		
		# Layout
		WtfGui.AutoLayout(self.table.layout,
			WtfGui.AutoLayout.Default(), WtfGui.AutoLayout.Default(), 
			WtfGui.LRInnerSizeOf(self.layout),
			WtfGui.LRInnerSizeOf(self.layout));
			
		self.AddChild(self.table);
		
		self.innerSize.x = 600;
		
	def AddObject(self, t):
		rec = self.table.AddRecord();
		rec.AddChild(WtfGui.Button(Function(lambda:
			Controller.GetInst().currentPlayer.AddWindow(Trader(t))),
			"Trader", font));
			
		supply = []; demand = [];
		for (n, d) in t.demand.iteritems():
			if d < 0:
				supply.append(n);
			elif d > 0:
				demand.append(n);
		if len(supply) == 0:
			supply = [""];
		if len(demand) == 0:
			demand = [""];
		
		rec.AddChild(WtfGui.Label(reduce(lambda a,b: a + ", " + b, supply), font));
		rec.AddChild(WtfGui.Label(reduce(lambda a,b: a + ", " + b, demand), font));
		
class Trader(WtfGui.Window):
	def __init__(self, trader):
		WtfGui.Window.__init__(self, "Trader");
		
		self.trader = trader;
		
		self.table = WtfGui.Table(WtfGui.ScrollLayoutCreationOptions(), 1);
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 7.0, WtfGui.Label("Commodity", font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 7.0, WtfGui.Label("Sale Price", font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 7.0, WtfGui.Label("Max Purchase Price", font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 7.0, WtfGui.Label("Volume", font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 7.0, WtfGui.Label("Mkt. Cap", font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 7.0, WtfGui.Label("Consumption", font)));
		self.table.AddHeading(WtfGui.TableHeading(1.0 / 7.0, WtfGui.Label("Demand", font)));
		
		# Update
		map(lambda (k,v): self.AddObject(k, v), trader.commodities.iteritems());
		
		# Layout
		WtfGui.AutoLayout(self.table.layout,
			WtfGui.AutoLayout.Default(), WtfGui.AutoLayout.Default(), 
			WtfGui.LRInnerSizeOf(self.layout),
			WtfGui.LRInnerSizeOf(self.layout).Then(WtfGui.LRDisplacement(-30)));
			
		self.AddChild(self.table);
		
		self.innerSize = iVector2D(600, 400);
		
	def AddObject(self, n, tc):
		rec = self.table.AddRecord();
		rec.AddChild(WtfGui.Label(n, font));
		rec.AddChild(WtfGui.Label(str(tc.price), font));
		rec.AddChild(WtfGui.Label(str(tc.maxPrice), font));
		rec.AddChild(WtfGui.Label(str(tc.commodity.amt), font));
		rec.AddChild(WtfGui.Label(str(tc.commodity.amt * tc.price), font));
		
		if n in self.trader.demand:
			demand = str(self.trader.demand[n]);
		else:
			demand = "0";
		rec.AddChild(WtfGui.Label(demand, font));
		rec.AddChild(WtfGui.Label(str(tc.demand), font));
		
class GovtReserves(WtfGui.Window):
	def __init__(self, society):
		WtfGui.Window.__init__(self, "Government Reserves");
		
		self.innerSize.x = 600;
		self.society = society;
		
		ctr = WtfGui.LayoutContainer(WtfGui.LayoutContainerCreationOptions(), 1);
		self.AddChild(ctr);
		
		lbl = WtfGui.Label("Buy and sell government commodity reserves.", font);
		lbl.size = iVector2D(self.innerSize.x, 20);
		ctr.AddChild(lbl);
		
		self.table = WtfGui.Table(WtfGui.ScrollLayoutCreationOptions(), 1);
		self.table.size = self.innerSize - iVector2D(0, lbl.size.y);
		self.table.AddHeading(WtfGui.TableHeading(self.innerSize.x / 4, WtfGui.Label("Commodity", font)));
		self.table.AddHeading(WtfGui.TableHeading(self.innerSize.x / 4, WtfGui.Label("Price", font)));
		self.table.AddHeading(WtfGui.TableHeading(self.innerSize.x / 4, WtfGui.Label("Sell", font)));
		self.table.AddHeading(WtfGui.TableHeading(self.innerSize.x / 4, WtfGui.Label("Buy", font)));
		
		self.UpdateTable();
	
	def UpdateTable(self):
		data = Controller.GetInst().GetGlobalMarketData();
		cs = self.society.GetGovtReserves();
		
		for (n, c) in cs.iteritems():
			if n in data:
				return 0;

class News(WtfGui.Window):
	def __init__(self):
		game = Controller.GetInst().game;
		wm = Controller.GetInst().gameWm;
		
		WtfGui.Window.__init__(self, game.GetDateString() + " - Turn " + str(game.turn));
		
		self.unreadItems = WtfGui.Table(WtfGui.ScrollLayoutCreationOptions(), 1);
		self.unreadItems.AddHeading(WtfGui.TableHeading(1.0, WtfGui.Label("Unread News", font)));
		
		self.readItems = WtfGui.Table(WtfGui.ScrollLayoutCreationOptions(), 1);
		self.readItems.AddHeading(WtfGui.TableHeading(1.0, WtfGui.Label("Read News", font)));
		
		for item in game.newsItems:
			row = self.unreadItems.AddRecord();
			row.AddChild(WtfGui.Button(Function(lambda: self.ReadItem(item, row)),
				item.text, font));
		
		WtfGui.AutoLayout(self.unreadItems.layout,
			WtfGui.AutoLayout.Default(), WtfGui.AutoLayout.Default(), 
			WtfGui.LRInnerSizeOf(self.layout),
			WtfGui.LRInnerSizeOf(self.layout).Then(WtfGui.LRScale(0.5)));
		WtfGui.AutoLayout(self.readItems.layout,
			WtfGui.AutoLayout.Default(),
			WtfGui.AutoLayout.PositionAfter(self.unreadItems.layout), 
			WtfGui.LRInnerSizeOf(self.layout),
			WtfGui.LRInnerSizeOf(self.layout).Then(WtfGui.LRScale(0.5)));
			
		self.AddChild(self.unreadItems);
		self.AddChild(self.readItems);
		
	def ReadItem(self, item, row):
		row.Remove();
		self.readItems.AddChild(row);
		
class Help(WtfGui.Window):
	def __init__(self, wm):
		WtfGui.Window.__init__(self, "Help");
		
		self.font = WtfGui.Font("v_gui_font");
		self.wm = wm;
		self.innerSize.x = 600;
		
		self.table = WtfGui.Table(WtfGui.ScrollLayoutCreationOptions(), 1);
		self.table.AddHeading(WtfGui.TableHeading(1.0,
			WtfGui.Label("Item", self.font)));
		WtfGui.AutoLayout(self.table.layout,
			WtfGui.AutoLayout.Default(), WtfGui.AutoLayout.Default(), 
			WtfGui.LRInnerSizeOf(self.layout), WtfGui.LRInnerSizeOf(self.layout));
		self.AddChild(self.table);
		
		map(lambda t: self.AddTechnology(t), Technology.gTechnologies);
		
	def AddTechnology(self, t):
		rec = self.table.AddRecord();
		rec.AddChild(WtfGui.Button(Function(
			lambda: self.wm.AddWindow(TechnologyHelp(t, self.wm), True)), t.name, self.font));


class TechnologyHelp(WtfGui.Window):
	def __init__(self, t, wm):
		WtfGui.Window.__init__(self, "Help: " + t.name);
		
		self.innerSize = iVector2D(400, 450);
		
		ctr = WtfGui.LayoutContainer(WtfGui.LayoutContainerCreationOptions(), 1);
		
		lbl = WtfGui.Label(t.description, font);
		lbl.size = iVector2D(self.innerSize.x, 60);
		ctr.AddChild(lbl);
		
		preqsCtr = WtfGui.LayoutContainer(WtfGui.LayoutContainerCreationOptions(), 0);
		lbl = WtfGui.Label("Prequisites", font);
		lbl.ExpandToText();
		preqsCtr.AddChild(lbl);
		preqs = WtfGui.LayoutContainer(WtfGui.LayoutContainerCreationOptions(), 1);
		preqsCtr.AddChild(preqs);
		
		def AddPreq(pt):
			btn = WtfGui.Button(Function(
				lambda: wm.AddWindow(TechnologyHelp(pt, wm), True)), pt.name, font);
			btn.ExpandToText();
			preqs.AddChild(btn);
		for p in t.preqs:
			AddPreq(p());
			
			
		ctr.AddChild(preqsCtr);
		self.AddChild(ctr);
		
class GameMenu(WtfGui.WindowManager):
	def __init__(self):
		
		WtfGui.WindowManager.__init__(self);
		
		ctrOpts = WtfGui.LayoutContainerCreationOptions();
		
		# Create menu
		font = WtfGui.Font("v_gui_font");

		self.menu = WtfGui.Menu("Game Menu");
		self.menu.Resize(300, 100);

		self.menu.AddChild(WtfGui.Button(Function
			(lambda: self.WmToggle()), "Resume Game", font));
		self.menu.AddChild(WtfGui.Button(Function
			(lambda: gWm.AddWindow(Options(font), 1)), "Options", font));
		self.menu.AddChild(WtfGui.Button(Function
			(lambda: self.SpawnConsole()), "Developer's Console", font));
		self.menu.AddChild(WtfGui.Button(Function
			(lambda: self.AddWindow(WtfGui.SceneDiagnostics(), 1)), "Diagnostics", font));
		self.menu.AddChild(WtfGui.Button(Function(lambda: exit()), "Exit", font));
		
		# Add elements
		self.AddChild(WtfGui.LayoutPositioner(self.menu, WtfGui.CentrePositioner(), WtfGui.CentrePositioner()));
		